package cn.ex.ymcc.service.impl;

import cn.ex.ymcc.constants.BaseConstants;
import cn.ex.ymcc.constants.MineError;
import cn.ex.ymcc.domain.*;
import cn.ex.ymcc.feign.LoginFeignClient;
import cn.ex.ymcc.mapper.UserMapper;
import cn.ex.ymcc.result.JSONResult;
import cn.ex.ymcc.service.IBlacklistService;
import cn.ex.ymcc.service.IUserAccountService;
import cn.ex.ymcc.service.IUserBaseInfoService;
import cn.ex.ymcc.service.IUserService;
import cn.ex.ymcc.util.AssertUtil;
import cn.ex.ymcc.util.Base64Util;
import cn.ex.ymcc.util.BitStatesUtils;
import cn.ex.ymcc.util.GetIpUtil;
import cn.ex.ymcc.vo.RegisterDto;
import com.alibaba.nacos.client.utils.IPUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author aze
 * @since 2022-07-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private LoginFeignClient loginFeignClient;
    @Autowired
    private IUserBaseInfoService userBaseInfoService;
    @Autowired
    private IUserAccountService userAccountService;

    @Autowired
    private IBlacklistService blacklistService;

    /**
     *添加黑名单
     * @param entity
     * @return
     */
    @Override
    public JSONResult updateBlackListState(User entity) {
        entity.setBlacklistState(0);
        boolean b = updateById(entity);
        if(b) {
            Blacklist blacklist = new Blacklist();
            blacklist.setIp(GetIpUtil.getIp());
            blacklist.setLoginId(entity.getLoginId());
            blacklist.setUserId(entity.getId());
            blacklist.setPhone(entity.getPhone());
            //保存黑名单表
            blacklistService.insert(blacklist);
        }
        return JSONResult.success();
    }

    /**
     * 注册
     * @param dto
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)  //开启分布式事务管理
    public void register(RegisterDto dto) {
        String smsKey = String.format(BaseConstants.User.REGISTER_PHONE_PRIFIX , dto.getMobile());//register:158234234
        String smsVaule = (String)redisTemplate.opsForValue().get(smsKey);
        AssertUtil.isNotNull(smsVaule, MineError.USER_SMS_EMPTY.getMessage());

        AssertUtil.isEquals(smsVaule,dto.getSmsCode(),MineError.USER_SMSCODE_NOT_EQUALS.getMessage());
        User user = selectByPhone(dto.getMobile());
        AssertUtil.isNull(user,MineError.USER_EXISTS.getMessage());
        //保存,返回自增id
        JSONResult jsonResult = saveLogin(dto);

        AssertUtil.isTrue(jsonResult.isSuccess(),jsonResult.getMessage());
        //login保存成功了
        AssertUtil.isNotNull(jsonResult.getData(),"登录信息保存失败！");
        Long loginId = Long.valueOf(jsonResult.getData().toString());


        user = saveUser(loginId,dto.getMobile());//返回自增id
        AssertUtil.isNotNull(user.getId(),"用户保存失败！！");
        //保存userBaseInfo
        initUserInfo(user.getId(),dto.getRegChannel());
        //保存userAccount
        initUserAccount(user.getId());
    }

    /**
     * 保存UserAccount
     * @param userId
     */
    private void initUserAccount(Long userId) {
        UserAccount account = new UserAccount();
        account.setId(userId);
        account.setCreateTime(new Date().getTime());
        userAccountService.insert(account);
    }

    /**
     * 保存UserInfo 表
     * @param userId
     * @param regChannel
     */
    private void initUserInfo(Long userId,Integer regChannel) {
        UserBaseInfo info = new UserBaseInfo();
        info.setId(userId);
        info.setCreateTime(new Date().getTime());
        info.setRegChannel(regChannel);//注册渠道
        userBaseInfoService.insert(info);
    }

    /**
     * 保存user表
     * @param loginId
     * @param mobile
     * @return
     */
    private User saveUser(Long loginId,String mobile) {
        User user = new User();
        user.setLoginId(loginId);
        user.setPhone(mobile);
        user.setNickName(mobile);
        user.setCreateTime(new Date().getTime());
        // 设置用户的位状态   注册成功  激活   手机认证
        long bitState = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);
        bitState = BitStatesUtils.addState(bitState, BitStatesUtils.OP_AUTHED_PHONE);
        user.setBitState(bitState);
        insert(user);
        return user;
    }

    /**
     * 保存login表
     * @param dto
     * @return
     */
    private JSONResult saveLogin(RegisterDto dto) {
        Login login = new Login();
        login.setUsername(dto.getMobile());
        login.setPassword(dto.getPassword());
        login.setType(Login.TYPE_USER);

        String password = dto.getPassword();
        String encodePassword = Base64Util.encode(password);
        login.setPassword(encodePassword);
        return loginFeignClient.save(login);
    }

    private User selectByPhone(String phone) {
        Wrapper<User> tWrapper = new EntityWrapper();
        //指定条件
        tWrapper.eq("phone",phone);
        return selectOne(tWrapper);
    }


}

